package com.sigmatrix.h5.redisson;

import java.util.concurrent.TimeUnit;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;

/**
 * redisson分布式锁
 * 
 * @author wei.wang
 *
 */
public class RedissonLocker implements DistributedLocker {
    
	private final static String LOCKER_PREFIX = "lock:";

	private RedissonClient redissonClient;


    @Override
    public void unlock(String lockKey) {
        RLock lock = redissonClient.getLock(LOCKER_PREFIX+lockKey);
        lock.unlock();
    }
    
    @Override
    public void lock(String lockKey, TimeUnit unit ,int timeout) {
        RLock lock = redissonClient.getLock(LOCKER_PREFIX+lockKey);
        lock.lock(timeout, unit);
    }

    public void setRedissonClient(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

	@Override
	public boolean isAvailable(String lockKey) {
		 RLock lock = redissonClient.getLock(LOCKER_PREFIX+lockKey);
		return !lock.isExists();
	}

	@Override
	public <T> T lockAndInvoke(String lockKey, LockedWorker<T> worker, long lockTime){
		RLock lock = redissonClient.getLock(LOCKER_PREFIX + lockKey);
		boolean success = false;
		try {
			success = lock.tryLock(100, lockTime, TimeUnit.MILLISECONDS);
		} catch (InterruptedException e) {
			throw new AquireLockException(e.getMessage(),e);
		}
		if (success) {
			try {
				return worker.invokeAfterLocked();
			} finally {
				lock.unlock();
			}
		}
		throw new AquireLockException("获取锁失败");
	}
}
